
// for mmap munmap
// mman -- memory management
#include <sys/mman.h>


#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>

int main() {
    const char *file_path = "example.txt";
    const char *file_content = "Hello, mmap! This is a demo.";
    size_t file_size = strlen(file_content);

    // 创建并写入文件
    int fd = open(file_path, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
    if (fd == -1) {
        perror("open");
        exit(EXIT_FAILURE);
    }
    if (write(fd, file_content, file_size) != file_size) {
        perror("write");
        close(fd);
        exit(EXIT_FAILURE);
    }
    lseek(fd, 0, SEEK_SET);  // 确保文件指针在文件开头

    // 使用mmap映射文件
    char *mapped = (char*)mmap(NULL, file_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (mapped == MAP_FAILED) {
        perror("mmap");
        close(fd);
        exit(EXIT_FAILURE);
    }

    // 读取并打印映射的内容
    printf("Mapped content: %s\n", mapped);

    // 修改映射的内容
    strncpy(mapped, "New content for mmap demo.", file_size);
    mapped[file_size - 1] = '\0';  // 确保字符串以null结尾

    // 刷新到文件（对于MAP_SHARED映射是必需的）
    if (msync(mapped, file_size, MS_SYNC) == -1) {
        perror("msync");
    }

    // 解除映射
    if (munmap(mapped, file_size) == -1) {
        perror("munmap");
    }

    // 关闭文件
    close(fd);

    // 验证文件内容是否已更改
    char buffer[file_size];
    fd = open(file_path, O_RDONLY);
    if (fd == -1) {
        perror("open");
        exit(EXIT_FAILURE);
    }
    if (read(fd, buffer, file_size - 1) != file_size - 1) {
        perror("read");
        close(fd);
        exit(EXIT_FAILURE);
    }
    buffer[file_size - 1] = '\0';  // 确保字符串以null结尾
    printf("File content after mmap: %s\n", buffer);

    close(fd);
    return 0;
}